home *** CD-ROM | disk | FTP | other *** search
/ Aminet 50 / Aminet 50 (2002)(GTI - Schatztruhe)[!][Aug 2002].iso / Aminet / util / libs / mpega_libmad.lha / mpega_libmad / support_pup.c < prev    next >
C/C++ Source or Header  |  2001-12-07  |  6KB  |  217 lines

  1. // =======================================================================
  2. // 68k side library startup and communications dispatcher
  3. // (c)1998 by Jacek Cybularczyk (NOE/VenusArt)
  4. // slightly modified for specific use by Sigbjørn (CISC) Skjæret
  5. // =======================================================================
  6.  
  7. #include "library_base.h"
  8.  
  9. #include <exec/execbase.h>
  10. #include <exec/memory.h>
  11. #include <dos/dostags.h>
  12. #include <utility/tagitem.h>
  13.  
  14. #include <powerup/ppclib/object.h>
  15. #include <powerup/ppclib/interface.h>
  16. #include <powerup/ppclib/message.h>
  17. #include <powerup/ppclib/tasks.h>
  18.  
  19. #include <proto/exec.h>
  20. #include <proto/dos.h>
  21. #include <proto/ppc.h>
  22.  
  23. struct Library *PPCLibBase = NULL;
  24. extern UBYTE _ElfObject;
  25.  
  26. ULONG InitDispatch(struct PrivateBase *PrivateBase, ULONG MsgType)
  27. {
  28.     struct TagItem tmpTagList[20];
  29.  
  30.     tmpTagList[0].ti_Tag = TAG_DONE;
  31.     if ((PrivateBase->pv_ReplyPort = PPCCreatePort(tmpTagList)))
  32.     {
  33.         if ((PrivateBase->pv_StartupMsg = PPCCreateMessage(PrivateBase->pv_ReplyPort, sizeof(struct StartupData))))
  34.         {
  35.             if ((PrivateBase->pv_StartupData = PPCAllocVec(sizeof(struct StartupData), MEMF_PUBLIC)))
  36.             {
  37.                 PrivateBase->pv_StartupData->ElfObject = PrivateBase->pv_ElfObject;
  38.  
  39.                 tmpTagList[0].ti_Tag = PPCTASKTAG_STARTUP_MSG;
  40.                 tmpTagList[0].ti_Data = (ULONG)PrivateBase->pv_StartupMsg;
  41.  
  42.                 tmpTagList[1].ti_Tag = PPCTASKTAG_STARTUP_MSGDATA;
  43.                 tmpTagList[1].ti_Data = (ULONG)PrivateBase->pv_StartupData;
  44.  
  45.                 tmpTagList[2].ti_Tag = PPCTASKTAG_STARTUP_MSGLENGTH;
  46. //                tmpTagList[2].ti_Data = sizeof(struct StartupData);
  47.                 tmpTagList[2].ti_Data = 0;
  48.  
  49.                 tmpTagList[3].ti_Tag = PPCTASKTAG_STARTUP_MSGID;
  50.                 tmpTagList[3].ti_Data = 0;
  51.  
  52.                 tmpTagList[4].ti_Tag = PPCTASKTAG_MSGPORT;
  53.                 tmpTagList[4].ti_Data = TRUE;
  54.  
  55.                 tmpTagList[5].ti_Tag = PPCTASKTAG_NAME;
  56.                 tmpTagList[5].ti_Data = (ULONG)PrivateBase->pv_Lib.lib_Node.ln_Name;
  57.  
  58.                 tmpTagList[6].ti_Tag = PPCTASKTAG_STACKSIZE;
  59.                 tmpTagList[6].ti_Data = 16384;
  60.  
  61.                 tmpTagList[7].ti_Tag = PPCTASKTAG_INPUTHANDLE;
  62. //                tmpTagList[7].ti_Data = (ULONG)Input();
  63.                 tmpTagList[7].ti_Data = NULL;
  64.             
  65.                 tmpTagList[8].ti_Tag = PPCTASKTAG_OUTPUTHANDLE;
  66. //                tmpTagList[8].ti_Data = (ULONG)Output();
  67.                 tmpTagList[8].ti_Data = NULL;
  68.  
  69.                 tmpTagList[9].ti_Tag = PPCTASKTAG_ERRORHANDLE;
  70. //                tmpTagList[9].ti_Data = (ULONG)Open("*", MODE_NEWFILE);
  71.                 tmpTagList[9].ti_Data = NULL;
  72.  
  73.                 tmpTagList[10].ti_Tag = NP_CloseInput;
  74.                 tmpTagList[10].ti_Data = FALSE;
  75.  
  76.                 tmpTagList[11].ti_Tag = NP_CloseOutput;
  77.                 tmpTagList[11].ti_Data = FALSE;
  78.  
  79.                 tmpTagList[12].ti_Tag = NP_CloseError;
  80.                 tmpTagList[12].ti_Data = FALSE;
  81.  
  82.                 tmpTagList[13].ti_Tag = TAG_DONE;
  83.  
  84.                 if ((PrivateBase->pv_Task = PPCCreateTask(PrivateBase->pv_ElfObject, tmpTagList)))
  85.                 {
  86.                     if ((PrivateBase->pv_PPCPort = (APTR)PPCGetTaskAttrsTags(PrivateBase->pv_Task, PPCTASKINFOTAG_MSGPORT, 0, TAG_END)))
  87.                     {
  88.                         if ((PrivateBase->pv_CallPPCMsg = PPCCreateMessage(PrivateBase->pv_ReplyPort, sizeof(struct CallPPCData))))
  89.                         {
  90.                             if ((PrivateBase->pv_CallPPCData = PPCAllocVec(sizeof(struct CallPPCData), MEMF_PUBLIC)))
  91.                             {
  92.                                 PrivateBase->pv_CallPPCData->Type = MsgType;
  93.                                 PrivateBase->pv_CallPPCData->Return = 0;
  94.  
  95.                                 PPCSendMessage(PrivateBase->pv_PPCPort, PrivateBase->pv_CallPPCMsg, PrivateBase->pv_CallPPCData, sizeof(struct CallPPCData), 0x12345678);
  96.                                 PPCWaitPort(PrivateBase->pv_ReplyPort);
  97.                                 PPCGetMessage(PrivateBase->pv_ReplyPort);
  98.  
  99.                                 return PrivateBase->pv_CallPPCData->Return;
  100.                             }
  101.  
  102.                             PPCDeleteMessage(PrivateBase->pv_CallPPCMsg);
  103.                         }
  104.                     }
  105.  
  106.                     /* TODO: Kill still active task */
  107.                 }
  108.  
  109.                 PPCFreeVec(PrivateBase->pv_StartupData);
  110.             }
  111.  
  112.             PPCDeleteMessage(PrivateBase->pv_StartupMsg);
  113.         }
  114.  
  115.         PPCDeletePort(PrivateBase->pv_ReplyPort);
  116.     }
  117.  
  118.     return 0;
  119. }
  120.  
  121. void RemoveDispatch(struct PrivateBase *PrivateBase, ULONG MsgType)
  122. {
  123.     if (PrivateBase->pv_CallPPCData)
  124.     {
  125.         PrivateBase->pv_CallPPCData->Type = MsgType;
  126.         PPCSendMessage(PrivateBase->pv_PPCPort, PrivateBase->pv_CallPPCMsg, PrivateBase->pv_CallPPCData, sizeof(struct CallPPCData), 0x12345678);
  127.  
  128.         while (PPCGetMessage(PrivateBase->pv_ReplyPort) != PrivateBase->pv_StartupMsg)
  129.         {
  130.             PPCWaitPort(PrivateBase->pv_ReplyPort);
  131.         }
  132.  
  133.         PPCFreeVec(PrivateBase->pv_CallPPCData);
  134.     }
  135.  
  136.     if (PrivateBase->pv_CallPPCMsg)
  137.         PPCDeleteMessage(PrivateBase->pv_CallPPCMsg);
  138.  
  139.     if (PrivateBase->pv_StartupMsg)
  140.         PPCDeleteMessage(PrivateBase->pv_StartupMsg);
  141.  
  142.     if (PrivateBase->pv_StartupData)
  143.         PPCFreeVec(PrivateBase->pv_StartupData);
  144.  
  145.     if (PrivateBase->pv_ReplyPort)
  146.         PPCDeletePort(PrivateBase->pv_ReplyPort);
  147. }
  148.  
  149. ULONG InitSupport(struct PrivateBase *PrivateBase)
  150. {
  151.     struct PPCObjectInfo PPCObjectInfo;
  152.  
  153.     if ((PPCLibBase = OpenLibrary("ppc.library", 0)))
  154.     {
  155.         PrivateBase->pv_PPCLibBase = PPCLibBase;
  156.  
  157.         if ((PrivateBase->pv_ElfObject = PPCLoadObjectTags(PPCELFLOADTAG_ELFADDRESS, (ULONG)&_ElfObject, PPCELFLOADTAG_ELFNAME, (ULONG)PrivateBase->pv_Lib.lib_Node.ln_Name, TAG_DONE)))
  158.         {
  159.             PPCObjectInfo.Address = 0L;
  160.             PPCObjectInfo.Name = "__LibFuncTable";
  161.  
  162.             PPCGetObjectAttrs(PrivateBase->pv_ElfObject, &PPCObjectInfo, NULL);
  163.             PrivateBase->pv_LibFuncTable = (APTR)PPCObjectInfo.Address;
  164.  
  165.             if (InitDispatch(PrivateBase, MSGTYPE_INIT))
  166.             {
  167.                 /* We can't re-use the ReplyPort because we are on ramlib's context, so clean up */
  168.                 while (PPCGetMessage(PrivateBase->pv_ReplyPort) != PrivateBase->pv_StartupMsg)
  169.                 {
  170.                     PPCWaitPort(PrivateBase->pv_ReplyPort);
  171.                 }
  172.  
  173.                 PrivateBase->pv_Task = NULL;
  174.                 PrivateBase->pv_PPCPort = NULL;
  175.  
  176.                 PPCDeleteMessage(PrivateBase->pv_CallPPCMsg);
  177.                 PrivateBase->pv_CallPPCMsg = NULL;
  178.  
  179.                 PPCDeleteMessage(PrivateBase->pv_StartupMsg);
  180.                 PrivateBase->pv_StartupMsg = NULL;
  181.  
  182.                 PPCDeletePort(PrivateBase->pv_ReplyPort);
  183.                 PrivateBase->pv_ReplyPort = NULL;
  184.  
  185.                 PPCFreeVec(PrivateBase->pv_StartupData);
  186.                 PrivateBase->pv_StartupData = NULL;
  187.  
  188.                 return 1;
  189.             }
  190.  
  191.             PPCUnLoadObject(PrivateBase->pv_ElfObject);
  192.         }
  193.  
  194.         CloseLibrary(PPCLibBase);
  195.         PrivateBase->pv_PPCLibBase = PPCLibBase = NULL;
  196.     }
  197.  
  198.     return 0;
  199. }
  200.  
  201. void RemoveSupport(struct PrivateBase *PrivateBase)
  202. {
  203.     if (PPCLibBase)
  204.     {
  205.         InitDispatch(PrivateBase, MSGTYPE_HELLO);
  206.         RemoveDispatch(PrivateBase, MSGTYPE_REMOVE);
  207.  
  208.         if (PrivateBase->pv_ElfObject)
  209.             PPCUnLoadObject(PrivateBase->pv_ElfObject);
  210.  
  211.         if (PrivateBase->pv_PPCLibBase)
  212.             CloseLibrary(PrivateBase->pv_PPCLibBase);
  213.  
  214.         PrivateBase->pv_PPCLibBase = PPCLibBase = NULL;
  215.     }
  216. }
  217.